StepFunctions の Waitステートによる Lambda の遅延実行
渡辺です。 こういった小技、意外と検索しても出てこないですね。
一定時間または特定日時に処理を実行したい
Lambdaを 定期実行 するには、cronのように設定できる CloudWatch Eventsが便利です。 一方、 特定時間後 、もしくは 特定日時 に 1回だけ Lambdaを実行したいこともあります。 例えば、注文を受けて一定時間後に自動キャンセル、ブログの時限投稿などです。
このようなユースケースでは、Step Functions の Waitステートがベストです。
Wait ステート
Step FunctionsのWait ステートは、名前の通り、待機状態を作るステートです。 実行がWait ステートの時、料金は一切かかりません(厳密には状態遷移に料金はかかるが、1,000 回の状態遷移あたり 0.025 USD)。 待機時間は、最大で約1年待機することができます(厳密には全体の実行時間が合計1年まで)。 おまけに、待機時間は相対時間でも絶対時間でも指定できます!
ステートマシンの例
この例は、待機時間をパラメータとして受け取り、待機後にLambdaを実行するステートマシンです。
{ "StartAt": "Wait", "States": { "Wait": { "Type": "Wait", "SecondsPath": "$.wait_secs", "Next": "MainTask" }, "MainTask": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxx:function:main_task", "End": true } } }
入力パラメータの wait_secs
秒を待機し、 main_task 関数を実行します。
SecondsPath
は入力パラメータから相対時間(秒)を指定し、 Seconds
はステートマシンに待機する絶対時間を設定します。
そして、 TimestampPath
は入力パラメータから絶対日時を指定できます。
あまり使い道はありませんが、 Timestamp
を使い絶対日時を指定することもできます。
ステートマシンの起動
ステートマシンを起動するには、ステートマシンのARNと初期入力値を与えて、startExecution
を実行します。
const AWS = require('aws-sdk'); const StepFunctions = new AWS.StepFunctions(); const input = { wait_secs: 60 * 20, // 20 minitues other_param: 'Hello World' }; const params = { stateMachineArn: `arn:aws:states:ap-northeast-1:xxxxxxxxxxxxx:stateMachine:main_task_after_wait`, input: JSON.stringify(input) }; await StepFunctions.startExecution(params).promise(); };
まとめ
一定時間後に処理を実行するというのは、DBなどを利用してスケジューリングもできますが、とてつもなく面倒です。 AWSであれば、CloudWatch Eventsを作成して実行させることもできますが、 Step Function は、非常にシンプルに、低コストで実現できます。 また、リトライや処理失敗時のフォールバック処理も可能です。
なお、待機時間はステートマシンに固定することも、パラメータで与えることもできます。 詳しくはドキュメントを参照ください。